package Lab2;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.*;
import java.io.*;
import javax.swing.BoxLayout;
import javax.swing.JEditorPane;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

/**
 * A frame that has URL entry and displays web pages
 *
 * @author dale, Alex Lazarz for the back button and hypertext code.
 */
public class WebPageFrame extends JFrame implements ActionListener, HyperlinkListener {
    /** The initial size of the frame */
    public static final Dimension       FRAME_SIZE = new Dimension(800, 600);
    /** Pane that displays the web page */
    private JEditorPane     			webPagePane;
    /** Field for entering the URL */
    private JTextField      			urlField;
    /** Keep track of most recent url (for the history stack) */
    private URL             			currentURL = null;
    /** The actual Back button, so we have a variable to call for actions. */
    private JButton						backButton;
    /** A list of past URLs for use with the Back button. */
    private Stack<String>					URLStack;
    private String storedURL = "";
    
    public WebPageFrame () {
        // Instantiate data structures
    	URLStack = new Stack<String>();
    	
        // Instantiate GUI components
        webPagePane = new JEditorPane();
        urlField = new JTextField("http://", 40);
        backButton = new JButton("Back");

        // Set initial properties of GUI components
        webPagePane.setEditable(false);
        backButton.setEnabled(false);

        // Register callbacks
        urlField.addActionListener(this);
        backButton.addActionListener(this);
        webPagePane.addHyperlinkListener(this);

        // Lay out the GUI components
        layoutGUI();

        // If the user clicks on the window close button, exit
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    /**
     * Lay out the GUI components
     */
    private void layoutGUI() {
        // Layout the top mainPanel for user input
        JPanel topPanel = new JPanel();
        BoxLayout topLayout = new BoxLayout(topPanel, BoxLayout.X_AXIS);
        topPanel.setLayout(topLayout);
        topPanel.add(backButton);
        topPanel.add(new JLabel("Web Site: "));
        topPanel.add(urlField);
        topPanel.add(new JPanel());

        // The webPagePane is viewed through a scrollPane
        JScrollPane scroller = new JScrollPane(webPagePane);

        // Add the scroller, which views the mainPanel to the frame's container
        Container c = this.getContentPane();
        c.setLayout(new BorderLayout());
        c.add(topPanel, BorderLayout.NORTH);
        c.add(scroller, BorderLayout.CENTER);

        // Set the default size and make the frame visible
        this.setSize(FRAME_SIZE);
        this.setPreferredSize(FRAME_SIZE);
        this.setVisible(true);
    }

    /**
     * Set the web page to view
     *
     * @param url The URL of the web page
     */
    private void setEditorPaneURL (URL url) {
        if (url != null) {
            try {
                webPagePane.setPage(url);
                urlField.setText(url.toString());
            } catch (IOException ex) {
                webPagePane.setText ("Unable to read from: " + url);
            }
        } else {
            webPagePane.setText ("Couldn't find the URL");
        }
    }

    /**
     * hyperlinkUpdate - Triggers whenever the user clicks on a hypertext link.
     * 
     * @param e - The event that occurs when the user scrolls over or clicks a hypertext link.
     */
	public void hyperlinkUpdate(HyperlinkEvent e) {
		if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
			URL webSite = null;

            URLStack.push(urlField.getText());
			webSite = e.getURL();
			urlField.setText((String) e.getDescription());
            setEditorPaneURL (webSite);
		}
		
		if (URLStack.size() >= 1) {
			backButton.setEnabled(true);
		}
	}

    /**
     * Handle events from the URL field and the backButton
     *
     * @param ev The event
     */
    public void actionPerformed (ActionEvent ev) {
        if (ev.getSource() == urlField) {
        	
        	if (URLStack.size() == 0) {
        		if (storedURL != "") {
        			URLStack.push(storedURL);
        		}
        	}
        	
            URLStack.push(urlField.getText());
            URL webSite = null;
            try {
                webSite = new URL(urlField.getText());
                setEditorPaneURL (webSite);
            } catch (MalformedURLException ex) {
                webPagePane.setText(urlField.getText() + " has a bad URL format");
            }
            
            if (URLStack.size() > 0) {
            	backButton.setEnabled(true);
            }
        }
        
        if (ev.getSource() == backButton) {
        	if (URLStack.peek() != null) {
        		storedURL = urlField.getText();
        		urlField.setText(URLStack.pop());
        	}
        	
        	if (URLStack.size() == 0) {
        		backButton.setEnabled(false);
        		
        		URL webSite = null;
                try {
                    webSite = new URL(urlField.getText());
                    setEditorPaneURL (webSite);
                } catch (MalformedURLException ex) {
                    webPagePane.setText(urlField.getText() + " has a bad URL format");
                }
                
                return;
        	}
        	
        	if (urlField.getText().equals(storedURL)) {
        		if (URLStack.size() > 0) {
        			urlField.setText(URLStack.pop());
        		}
        	}
        	
        	if (URLStack.size() == 0) {
        		backButton.setEnabled(false);
        	}
        	
            URL webSite = null;
            try {
                webSite = new URL(urlField.getText());
                setEditorPaneURL (webSite);
            } catch (MalformedURLException ex) {
                webPagePane.setText(urlField.getText() + " has a bad URL format");
            }
        }
    }

    /** This allows us to run this class as a simple application.
     *  We can also use this class as a re-useable component
     *
     *  @param args Not Used
     */
    public static void main(String[] args) {
        new WebPageFrame();
    }
}
